﻿using EasyNetQ;
using EasyNetQ.Topology;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Concurrent;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using VOL.Core.Utilities;
using VOL.Entity.DomainModels;
using VOL.WebApi.Controllers.MqDataHandle;

namespace VOL.WebApi.Controllers
{
    /// <summary>
    /// MQ消息发布 订阅
    /// </summary>
    [Produces("application/json")]
    [Route("api/Client")]
    public class ClientController : Controller
    {
        //private readonly IClientService clientService;
      //  private readonly IBus bus;
        private static IMemoryCache _cache = new MemoryCache(new MemoryCacheOptions());
        // 线程安全的队列，用于缓存RabbitMQ消息
        private static ConcurrentQueue<string> _messageQueue = new ConcurrentQueue<string>();

        //public ClientController(IClientService _clientService, IBus bus)
        public ClientController(IBus bus)
        {
            //clientService = _clientService;
        //    this.bus = bus;

        }

       

        /// <summary>
        /// MQ消息发布
        /// </summary>
        /// <param name="clientDto"></param>
        /// <returns></returns>

        [HttpPost]
        public async Task<string> Post([FromBody] ClientDTO clientDto)
        {
            // Business Logic here...
            // eg.Add new client to your service databases via EF
            // Sample Publish
            //var bus = RabbitHutch.CreateBus("host=192.168.110.246;virtualHost=/;username=admin;password=123456");
            var bus = RabbitHutch.CreateBus("host=192.168.110.183;username=admin;password=123456");
            var advancedBus = bus.Advanced;
            var message = new Message<object>(clientDto.Name);
            await advancedBus.PublishAsync(Exchange.Default, "test1", false, message);



            ////订阅TSysLogVis日志 - 请不要在两次发布之间重复使用它
            //var queue = advancedBus.QueueDeclare("test");

            //advancedBus.Consume(queue, async (body, properties, info) =>
            //{
            //    try
            //    {
            //        var message = Encoding.UTF8.GetString(body.ToArray());
            //        //var data = JsonConvert.DeserializeObject<TSysLogVis>(message);
            //        Console.WriteLine($"消息处理 {DateTime.Now} : {message}");
            //        //db.Insertable(data).SplitTable().ExecuteReturnSnowflakeId();
            //    }
            //    catch (Exception ex)
            //    {
            //        // 处理异常，例如记录日志或重新抛出
            //        Console.Error.WriteLine($"处理消息时发生异常: {ex}");
            //    }
            //});
            return "Add Client Success! You will receive some letter later.";
        }
       
        /// <summary>
        /// MQ消息订阅
        /// </summary>
        /// <param name="clientDto"></param>
        /// <returns></returns>
        [HttpPost, Route("RMGet")]
        public async Task<string> Get([FromBody] ClientDTO clientDto)
        {
            //var bus = RabbitHutch.CreateBus("host=192.168.1.107;virtualHost=/;username=admin;password=123456");
            var bus = RabbitHutch.CreateBus("host=192.168.110.183;username=admin;password=123456");
           
            var advancedBus = bus.Advanced;
       
            //订阅TSysLogVis日志 - 请不要在两次发布之间重复使用它
            var queue = await advancedBus.QueueDeclareAsync("test1");
            while (true)
            {
                Thread.Sleep(200);
                advancedBus.Consume(queue, async (body, properties, info) =>
            {

                try
                {
                    var message = Encoding.UTF8.GetString(body.ToArray());
                    Console.WriteLine($"消息处理 {DateTime.Now} : {message}");
                    // 缓存消息
                    CacheMessage(message);
                   
                }
                catch (Exception ex)
                {
                    // 处理异常，例如记录日志或重新抛出
                    Console.Error.WriteLine($"处理消息时发生异常: {ex}");
                }

                Thread.Sleep(200);
            });
                // 在退出前，你可以处理队列中的消息
            return    ProcessMessageQueue();

            }

        }
        private static void CacheMessage(string message)
        {
            // 使用消息内容作为缓存键（或者你可以使用其他唯一标识符）
            var cacheKey = message;

            // 将消息缓存起来，设置一个过期时间（例如1小时）
            _cache.Set(cacheKey, message, TimeSpan.FromHours(1));
           var s= _cache.Get(cacheKey);
            // 将消息添加到队列中
            _messageQueue.Enqueue(message);
            Console.WriteLine($"Message '{message}' has been cached.");
        }
        private static string ProcessMessageQueue()
        {
            while (!_messageQueue.IsEmpty)
            {
                if (_messageQueue.TryDequeue(out string message))
                {
                    // 在这里处理消息
                    Console.WriteLine($"Processing message: {message}");
                    // ... 你的处理逻辑 ...
                    return message;
                }
                // 可以在这里加入适当的延迟，以避免过快地处理消息
                Thread.Sleep(100); // 示例延迟，实际使用时请根据需要调整
                return message;
            }
            return null;
        }
    }

}
